
/* class encapsulating a code derived from 
Gary McGuire's method of fast finding of all UA of size up to 12
applied to X+Y+27 (band1 filled) where each UA is in a 32bits field
*/
typedef unsigned char byte;
typedef unsigned short word;

struct SmallSet   {
   byte size;
   byte data[ 6 ];
};

struct UnavPat   {
   byte digits;             // # of different digits occurring
   SmallSet groups[ 6 ];   // each group consists of those cells containing the same digit
   // we only use groups[ 0 ], ..., groups[ digits - 1 ]
   int GetSize() const      {
      int size = 0;
      for ( int i = 0;  i < digits;  i++ )
         size += groups[ i ].size;
      return size;
   }
   void Print();
 };


struct UA : public BF3{
	int n,cells[12];
	inline void Initbf(){bf[0]=bf[1]=bf[2]=n=0; }
	void Otherbits(){bf[0]^= BIT_SET_27;bf[1]^= BIT_SET_27;bf[2]^= BIT_SET_27;}
	int Compare (UA & x);
	int SupersetOf(UA & x);// assumed *this > x
	void Print();

};



class UA_XY27{
public:

struct UAG : public UA{// part of UAG  used to load the table of UAs
	int nbox,tbox[6],omit,boxclues[6][9],nboxclues[6];
	BF3 boxpat[6];
	void BuildTbox();
	void Print(int index=0,int i=0);
	void PrintDet();
};
struct SPT{
	int ind,lim,ua;
	BF3 bf;
};


struct TUAG{
	char * puz0;
	UAG t[5000],wt;
	SPT spt[20],*s;
	int nua, ndisj,tdisj[20],nuafull,sourcecovered,ispot;


//	int indspot[20],UAspot[20],limspot[20],ispot;// Search 
	BF3 uabf[20],uabft[20],wb,bfunknown;
	int ttclues[80][10],ntclues[10],nactive,tw[80],ntw;// dichoclues
	int tcl[10],ncl;// clues in on UA
	int more1[80],nmore1; // in case needed form UAs out selected cells 

	void BuildTbox(){for(int i=0;i<nua;i++)t[i].BuildTbox();}	
	void PrintAll(){	for(int i=0;i<nua;i++)t[i].Print(1,i);	}
	void PrintAllFull();
	void PrintPerm();
	int AddUA();
	void Loadgamex(BF3 & x,int igame=0);
	void Loadgame0(BF3 & x);
	int Go_Perm(BF3 & wbf,BF3 & wbft);
	int SearchMore1();
	int SearchMore2();
	int SearchMoreAfter10();
	int Search10();
	int Search();
	int SearchOne();
	void CoverSourceAndAll(char * p);
	int CluesBox(BF3 & mybf,int n01);
	int CluesBoxold(BF3 & mybf,int n0,int firstcheck=1);
	int Count2();
	int Count3();
	int Count4();
	int Countx(int lim);
	int CountCluesInField(BF3 & mybf,int n0);
	void DumpPath();
}tuag;



private:
	byte * rows,*cols,backgrid[82];
	char entry[82],grid[82],
		entry0[82]; // entry switched to 0-8 values
	int transpose,opg;
//	void Solve54();
public:
//	UA_XY27();
	long long cpt[5];
	int opprint_uas,maxdisj;
	char ptest[82];
//	unsigned int 		unknown27[10];
	inline void Initcpt(){memset(cpt,0,sizeof cpt);}

	void CheckPattern( UnavPat & up);
	void CollectMoreUas();// so far all 1x2 1x3 2x2 2x3 (not 3x3)
	void CollectMoreGo1(char * puz,int ir,int ic,int transpose=0);
	void CollectMoreGo(char * puz, int ir,int ic,int transpose=0);
	int Filter17(char * puz);

};